package com.sunwayworld.common.utils;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.ResultSetMetaData;
import java.sql.Date;
import java.lang.reflect.Method;
import java.lang.reflect.InvocationTargetException;
import java.util.Enumeration;
import java.util.HashMap;
import java.sql.Timestamp;

import javax.servlet.http.HttpServletRequest;

import com.sunwayworld.common.utils.ObjectUtils;
import com.sunwayworld.common.utils.StringUtils;

public class BeanUtils {

	public static void copyProperties(Object provide, Object accept) {
		if (provide == null || accept == null)
			return;
		Method[] mProvide = provide.getClass().getMethods();
		Method[] mAccept = accept.getClass().getMethods();
		for (int i = 0; i < mProvide.length; i++) {
			String mProvideName = mProvide[i].getName();
			if ("get".equals(mProvideName.substring(0, 3))
					|| "is".equals(mProvideName.subSequence(0, 2))) {

				String tempProvidePropertie = null;
				if ("get".equals(mProvideName.substring(0, 3))) {
					tempProvidePropertie = mProvideName.substring(3,
							mProvideName.length()).toUpperCase();
				}
				if ("is".equals(mProvideName.substring(0, 2))) {
					tempProvidePropertie = mProvideName.substring(2,
							mProvideName.length()).toUpperCase();
				}
				
				for (int j = 0; j < mAccept.length; j++) {
					String mAcceptName = mAccept[j].getName();
					if ("set".equals(mAcceptName.substring(0, 3))) {
						String tempAcceptPropertie = mAcceptName.substring(3,
								mAcceptName.length()).toUpperCase();
						
						if (tempAcceptPropertie.equals(tempProvidePropertie)) {
							try {
								Object[] args = null;
								Object tempValue = mProvide[i].invoke(provide,
										args);
								Class cls = mAccept[j].getParameterTypes()[0];
								if (tempValue == null) {
									break;
								}
								Object val = infoEncode(tempValue, cls);
								Object[] temp = { val };

								mAccept[j].invoke(accept, temp);
							} catch (InvocationTargetException ex) {
							} catch (IllegalArgumentException ex) {
							} catch (IllegalAccessException ex) {
							}
							break;
						}
					}
				}
			}
		}
	}

	public static void copyProperties(ResultSet rs, Object accept) {
		if (rs == null || accept == null)
			return;
		Method[] mAccept = accept.getClass().getMethods();

		try {
			ResultSetMetaData rsmd = rs.getMetaData();
			for (int i = 1; i <= rsmd.getColumnCount(); i++) {
				String columnName = rsmd.getColumnName(i).toUpperCase();
				for (int j = 0; j < mAccept.length; j++) {
					Method tMethod = mAccept[j];
					String mName = tMethod.getName();
					String pName = mName.substring(3, mName.length())
							.toUpperCase();

					if (tMethod.getName().startsWith("set")
							&& columnName.equals(pName)) {
						Class cls = tMethod.getParameterTypes()[0];
						String par = cls.getName();
						try {
							if (par.equals("java.lang.String")) {
								String tmpValue = rs.getString(columnName);
								Object[] tmp = { tmpValue };
								tMethod.invoke(accept, tmp);
							}
							if (par.equals("java.lang.Integer")) {
								Integer tmpValue = new Integer(rs
										.getInt(columnName));
								Object[] tmp = { tmpValue };
								tMethod.invoke(accept, tmp);
							}
							if (par.equals("java.lang.Long")) {
								Long tmpValue = new Long(rs.getLong(columnName));
								Object[] tmp = { tmpValue };
								tMethod.invoke(accept, tmp);
							}
							if (par.equals("java.sql.Date")) {
								Date tmpValue = rs.getDate(columnName);
								Object[] tmp = { tmpValue };
								tMethod.invoke(accept, tmp);
							}
							if (par.equals("java.util.Date")) {
								Date tmpValue = rs.getDate(columnName);
								Object[] tmp = { tmpValue };
								tMethod.invoke(accept, tmp);
							}

							if (par.equals("java.sql.Timestamp")) {
								Timestamp tmpValue = rs
										.getTimestamp(columnName);
								Object[] tmp = { tmpValue };
								tMethod.invoke(accept, tmp);
							}
							if (par.equals("java.lang.Double")) {
								Double tmpValue = new Double(rs
										.getDouble(columnName));
								Object[] tmp = { tmpValue };
								tMethod.invoke(accept, tmp);
							}
							if (par.equals("java.lang.Float")) {
								Float tmpValue = new Float(rs
										.getFloat(columnName));
								Object[] tmp = { tmpValue };
								tMethod.invoke(accept, tmp);
							}
							if (par.equals("double")) {
								Double tmpValue = new Double(rs
										.getDouble(columnName));
								Object[] tmp = { tmpValue };
								tMethod.invoke(accept, tmp);
							}
							if (par.equals("int")) {
								Integer tmpValue = new Integer(rs
										.getInt(columnName));
								Object[] tmp = { tmpValue };
								tMethod.invoke(accept, tmp);
							}
							if (par.equals("float")) {

								Float tmpValue =

								new Float(rs.getFloat(columnName));

								Object[] tmp = { tmpValue };
								tMethod.invoke(accept, tmp);
							}
						} catch (InvocationTargetException ex) {
						} catch (IllegalArgumentException ex) {
						} catch (IllegalAccessException ex) {
						}
						break;
					}
				}
			}
		} catch (SQLException ex) {
		}

	}

	public static void setProperties(Object accept, Object data, String property) {
		Method[] mm = accept.getClass().getMethods();
		for (int i = 0; i < mm.length; i++) {
			if (mm[i].getName().toUpperCase().equals(
					"SET" + property.toUpperCase())) {
				Method cm = mm[i];
				Class[] acls = cm.getParameterTypes();
				if (acls.length != 1) {
					continue;
				}
				Class cls = acls[0];
				Object val = infoEncode(data, cls);
				Object[] args = { val };
				try {
					cm.invoke(accept, args);
				} catch (IllegalAccessException ex) {
				} catch (IllegalArgumentException ex) {
				} catch (InvocationTargetException ex) {
				}
				break;
			}
		}
	}

	public static Object infoEncode(Object obj, Class cls) {
		String pVal = StringUtils.toString(obj);
		return infoEncode(pVal, cls);
	}

	private static Object infoEncode(String mProviderValue, Class cls) {
		String className = cls.getName();
		if (className.equals("java.lang.String")) {
			return ObjectUtils.getString(mProviderValue);
		}
		if (className.equals("java.lang.Integer")) {
			return ObjectUtils.getInteger(mProviderValue);
		}
		if (className.equals("java.lang.Float")) {
			return ObjectUtils.getFloat(mProviderValue);
		}
		if (className.equals("java.lang.Long")) {
			return ObjectUtils.getLong(mProviderValue);
		}
		if (className.equals("java.lang.Double")) {
			return ObjectUtils.getDouble(mProviderValue);
		}
		if (className.equals("java.lang.Boolean")) {
			return ObjectUtils.getBoolean(mProviderValue);
		}
		if (className.equals("java.sql.Date")) {
			return ObjectUtils.getSqlDate(mProviderValue);
		}
		if (className.equals("java.util.Date")) {
			return ObjectUtils.getUtilDate(mProviderValue);
		}
		if (className.equals("java.sql.Timestamp")) {
			return ObjectUtils.getTimestamp(mProviderValue);
		}

		if (className.equals("double")) {
			return ObjectUtils.getDouble(mProviderValue);
		}
		if (className.equals("int")) {

			return ObjectUtils.getInteger(mProviderValue);
		}
		if (className.equals("float")) {
			return ObjectUtils.getFloat(mProviderValue);
		}
		if (className.equals("long")) {
			return ObjectUtils.getLong(mProviderValue);
		}
		if (className.equals("boolean")) {
			return ObjectUtils.getBoolean(mProviderValue);
		}

		return null;
	}

	public static HashMap rsultSetToHashMap(ResultSet rs) {
		HashMap<String, String> map = new HashMap<String, String>();
		try {
			ResultSetMetaData rsmd = rs.getMetaData();
			String colName = null;

			for (int i = 0; i < rsmd.getColumnCount(); i++) {
				colName = rsmd.getColumnName(i + 1);
				map.put(colName.toUpperCase(), rs.getString(colName));
			}
			return map;
		} catch (Exception ex) {
			return map;
		}
	}

	public static void copyProperties(HttpServletRequest request, Object accept) {

		if (accept == null || request == null) {
			return;
		}

		Enumeration provide = request.getParameterNames();

		Method[] mAccept = accept.getClass().getMethods();
		while (provide.hasMoreElements()) {

			String mProvideName = (String) provide.nextElement();

			if (mProvideName != null) {
				String tempProvidePropertie = mProvideName.toUpperCase();

				for (int j = 0; j < mAccept.length; j++) {
					String mAcceptName = mAccept[j].getName();
					if (mAcceptName.substring(0, 3).equals("set")) {
						String tempAcceptPropertie = mAcceptName.substring(3,
								mAcceptName.length()).toUpperCase();
						if (tempAcceptPropertie.equals(tempProvidePropertie)) {

							try {

								Object tempValue = request
										.getParameter(mProvideName);

								Class cls = mAccept[j].getParameterTypes()[0];
								if (tempValue == null || cls.isPrimitive()) {
									break;
								}

								Object temp[] = { infoEncode(
										(String) tempValue, cls) };
								mAccept[j].invoke(accept, temp);
							} catch (InvocationTargetException ex) {
								System.out
										.println("InvocationTargetException --"
												+ ex.getMessage());
							} catch (IllegalArgumentException ex) {
								System.out
										.println("IllegalArgumentException --"
												+ ex.getMessage());
							} catch (IllegalAccessException ex) {
								System.out.println("IllegalAccessException --"
										+ ex.getMessage());
							}
							break;
						}
					}
				}
			}
		}

	}

	public static void PrintValueObject(Object obj) {

		Method[] mm = obj.getClass().getMethods();
		for (int i = 0; i < mm.length; i++) {
			if (mm[i].getName().startsWith("get")
					&& mm[i].getParameterTypes().length == 0) {
				if (mm[i].getReturnType().isPrimitive()) {
					continue;
				}
				try {
					Object[] args = null;
					System.out.println(mm[i].getName() + "="
							+ StringUtils.toString(mm[i].invoke(obj, args)));
				} catch (InvocationTargetException ex) {
				} catch (IllegalArgumentException ex) {
				} catch (IllegalAccessException ex) {
				}
			}
		}

	}

}
